﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace WPControla.Client.ViewModels.Base
{
    /// <summary>
    /// Class to implement command infrastructure.
    /// </summary>
    public class DelegateCommand : ICommand
    {
        private Action _Execute;
        private Func<bool> _CanExecute;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="execute">Action to execute by the command</param>
        /// <param name="canExecute">Function to determine if the command can be executed.</param>
        public DelegateCommand(Action execute, Func<bool> canExecute)
        {
            _Execute = execute;
            _CanExecute = canExecute;
        }

        /// <summary>
        /// Constructor 
        /// </summary>
        /// <param name="execute">Action to execute by the command</param>
        public DelegateCommand(Action execute) : this(execute, null) { }

        /// <summary>
        /// Command can execute method. execute the function passed in the 
        /// constructor to determine if the command can be executed.
        /// </summary>
        /// <param name="parameter">parameter passed to the command.</param>
        /// <returns></returns>
        public bool CanExecute(object parameter)
        {
            if (_CanExecute != null)
                return _CanExecute.Invoke();
            else
                return true;
        }

        /// <summary>
        /// Event launched when the command change the posibility to execute.
        /// Received in the View.
        /// </summary>
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// Command Execute method, executes the Action method passed in the
        /// constructor.
        /// </summary>
        /// <param name="parameter"></param>
        public void Execute(object parameter)
        {
            _Execute();
        }
    }

    /// <summary>
    /// Generic parameter command
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class DelegateCommand<T> : ICommand
    {
        private Action<T> _execute;
        private Func<T, Boolean> _canExecute;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="execute">Action to execute by the command</param>
        /// <param name="canExecute">Function to determine if the command can be executed.</param>
        public DelegateCommand(Action<T> execute, Func<T, Boolean> canExecute)
        {
            _execute = execute;
            _canExecute = canExecute;
        }

        /// <summary>
        /// Constructor 
        /// </summary>
        /// <param name="execute">Action to execute by the command</param>
        public DelegateCommand(Action<T> execute) : this(execute, null) { }

        /// <summary>
        /// Command can execute method. execute the function passed in the 
        /// constructor to determine if the command can be executed.
        /// </summary>
        /// <param name="parameter">parameter passed to the command.</param>
        /// <returns></returns>
        public bool CanExecute(Object parameter)
        {
            if (_canExecute != null)
                return _canExecute((T)parameter);
            else
                return true;
        }

        /// <summary>
        /// Event launched when the command change the posibility to execute.
        /// Received in the View.
        /// </summary>
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// Command Execute method, executes the Action method passed in the
        /// constructor.
        /// </summary>
        /// <param name="parameter"></param>
        public void Execute(Object parameter)
        {
            if (CanExecuteChanged != null) { }

            if (_execute != null)
                _execute((T)parameter);
        }
    }
}
